using MediatR;
using S.O.Api.Write.Application.Command.Medical;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;
using System.Text.RegularExpressions;

namespace S.O.Api.Write.Application.Handler.Medical
{
    /// <summary>
    /// 创建患者信息处理器
    /// 负责患者信息的创建、验证和数据持久化
    /// </summary>
    public class CreatePatientHandler : IRequestHandler<CreatePatientCommand, APIResult<long>>
    {
        /// <summary>
        /// 患者信息仓储
        /// </summary>
        private readonly IBaseRepository<PatientModel> _patientRepository;
        
        /// <summary>
        /// 医疗卡信息仓储
        /// </summary>
        private readonly IBaseRepository<MedicalCardModel> _medicalCardRepository;
        
        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<CreatePatientHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化所需服务
        /// </summary>
        /// <param name="patientRepository">患者信息仓储</param>
        /// <param name="medicalCardRepository">医疗卡信息仓储</param>
        /// <param name="logger">日志记录器</param>
        public CreatePatientHandler(
            IBaseRepository<PatientModel> patientRepository,
            IBaseRepository<MedicalCardModel> medicalCardRepository,
            ILogger<CreatePatientHandler> logger)
        {
            _patientRepository = patientRepository;
            _medicalCardRepository = medicalCardRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理创建患者信息命令
        /// </summary>
        /// <param name="request">创建患者信息命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>包含患者ID的API结果</returns>
        public async Task<APIResult<long>> Handle(CreatePatientCommand request, CancellationToken cancellationToken)
        {
            try
            {
                // 验证必填字段
                if (string.IsNullOrWhiteSpace(request.PatientName))
                {
                    return new APIResult<long> { Code = APIEnums.Error, Msg = "患者姓名不能为空" };
                }
                
                if (string.IsNullOrWhiteSpace(request.IdCard))
                {
                    return new APIResult<long> { Code = APIEnums.Error, Msg = "身份证号不能为空" };
                }
                
                if (string.IsNullOrWhiteSpace(request.Phone))
                {
                    return new APIResult<long> { Code = APIEnums.Error, Msg = "联系电话不能为空" };
                }
                
                // 验证身份证号格式
                if (!IsValidIdCard(request.IdCard))
                {
                    return new APIResult<long> { Code = APIEnums.Error, Msg = "身份证号格式不正确" };
                }
                
                // 验证手机号格式
                if (!IsValidPhone(request.Phone))
                {
                    return new APIResult<long> { Code = APIEnums.Error, Msg = "手机号格式不正确" };
                }
                
                // 检查身份证号是否已存在
                var existingPatient = _patientRepository.GetALL()
                    .FirstOrDefault(p => p.IdCard == request.IdCard && !p.IsDeleted);
                
                if (existingPatient != null)
                {
                    // 如果患者已存在，更新信息并返回现有ID
                    existingPatient.PatientName = request.PatientName;
                    existingPatient.CardNo = request.CardNo;
                    existingPatient.Gender = request.Gender;
                    existingPatient.Age = request.Age;
                    existingPatient.BirthDate = request.BirthDate;
                    existingPatient.Phone = request.Phone;
                    existingPatient.Address = request.Address;
                    existingPatient.Ethnicity = request.Ethnicity;
                    existingPatient.Education = request.Education;
                    existingPatient.Occupation = request.Occupation;
                    existingPatient.PostalCode = request.PostalCode;
                    existingPatient.MaritalStatus = request.MaritalStatus;
                    existingPatient.IsEnable = true;
                    
                    _patientRepository.Update(existingPatient);
                    
                    _logger.LogInformation($"更新患者信息成功，患者ID: {existingPatient.Id}, 姓名: {request.PatientName}");
                    return new APIResult<long> { Code = APIEnums.Success, Data = existingPatient.Id, Msg = "患者信息更新成功" };
                }
                
                // 生成医疗卡号（如果未提供）
                if (string.IsNullOrWhiteSpace(request.CardNo))
                {
                    request.CardNo = GenerateCardNo();
                }
                
                // 创建新患者记录
                var patient = new PatientModel
                {
                    PatientName = request.PatientName,
                    CardNo = request.CardNo,
                    IdCard = request.IdCard,
                    Gender = request.Gender,
                    Age = request.Age,
                    BirthDate = request.BirthDate,
                    Phone = request.Phone,
                    Address = request.Address,
                    Ethnicity = request.Ethnicity,
                    Education = request.Education,
                    Occupation = request.Occupation,
                    PostalCode = request.PostalCode,
                    MaritalStatus = request.MaritalStatus,
                    IsEnable = true,
                    CreateTime = DateTime.Now
                };
                
                // 保存到数据库
                var result = _patientRepository.Create(patient);
                
                if (result > 0)
                {
                    // 创建医疗卡记录
                    var medicalCard = new MedicalCardModel
                    {
                        CardNo = patient.CardNo,
                        PatientId = patient.Id,
                        PatientName = patient.PatientName,
                        IdCard = patient.IdCard,
                        Phone = patient.Phone,
                        CardType = "新办",
                        CardFee = 10.00m,
                        CardStatus = "已办理",
                        IssueDate = DateTime.Now,
                        ActivateDate = DateTime.Now,
                        ExpiryDate = DateTime.Now.AddYears(5),
                        Operator = "系统",
                        IssueLocation = "挂号窗口",
                        Remarks = "系统自动办理",
                        IsFirstTime = true,
                        IsEnable = true,
                        CreateTime = DateTime.Now
                    };
                    
                    var cardResult = _medicalCardRepository.Create(medicalCard);
                    
                    if (cardResult > 0)
                    {
                        _logger.LogInformation($"创建患者信息和医疗卡成功，患者ID: {patient.Id}, 卡号: {patient.CardNo}, 姓名: {request.PatientName}");
                        return new APIResult<long> { Code = APIEnums.Success, Data = patient.Id, Msg = "患者信息和医疗卡创建成功" };
                    }
                    else
                    {
                        _logger.LogWarning($"患者信息创建成功但医疗卡创建失败，患者ID: {patient.Id}, 姓名: {request.PatientName}");
                        return new APIResult<long> { Code = APIEnums.Success, Data = patient.Id, Msg = "患者信息创建成功，但医疗卡创建失败" };
                    }
                }
                else
                {
                    _logger.LogError($"创建患者信息失败，姓名: {request.PatientName}");
                    return new APIResult<long> { Code = APIEnums.Error, Msg = "患者信息创建失败" };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"创建患者信息时发生异常，姓名: {request.PatientName}");
                return new APIResult<long> { Code = APIEnums.Error, Msg = "创建患者信息失败" };
            }
        }
        
        /// <summary>
        /// 验证身份证号格式
        /// </summary>
        /// <param name="idCard">身份证号</param>
        /// <returns>是否有效</returns>
        private bool IsValidIdCard(string idCard)
        {
            if (string.IsNullOrWhiteSpace(idCard))
                return false;
                
            // 18位身份证号正则表达式
            var pattern = @"^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$";
            return Regex.IsMatch(idCard, pattern);
        }
        
        /// <summary>
        /// 验证手机号格式
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <returns>是否有效</returns>
        private bool IsValidPhone(string phone)
        {
            if (string.IsNullOrWhiteSpace(phone))
                return false;
                
            // 手机号正则表达式
            var pattern = @"^1[3-9]\d{9}$";
            return Regex.IsMatch(phone, pattern);
        }
        
        /// <summary>
        /// 生成医疗卡号
        /// </summary>
        /// <returns>医疗卡号</returns>
        private string GenerateCardNo()
        {
            // 生成格式：年月日 + 4位随机数
            var dateStr = DateTime.Now.ToString("yyyyMMdd");
            var random = new Random().Next(1000, 9999);
            return $"{dateStr}{random}";
        }
    }
}